import Foundation
import Network
import NMSSH

import SystemConfiguration.CaptiveNetwork
import NetworkExtension

let DEFAULTIP = "192.168.4.1"

let YEHUODEFAULTIP = "10.42.0.1"

let DEFAULT_PORT = 8080

let YEHUO_PORT = 22

let USER = "cat"

let PASSWORD = "temppwd"

// 网络连接状态枚举
enum NetworkConnectionState {
    case disconnected
    case connecting
    case connected
    case error(Error)
}
@available(iOS 12.0, *)
// 数据传输协议
protocol DataTransferDelegate: AnyObject {
    func didReceiveData(_ data: Data, from connection: TCPConnection)
    func didSendData(_ data: Data, from connection: TCPConnection)
    func connectionStateDidChange(_ state: NetworkConnectionState, for connection: TCPConnection)
}
@available(iOS 12.0, *)
// MARK: - TCP连接管理
class TCPConnection {
    
    let connection: NWConnection
    let id: String
    var state: NetworkConnectionState = .disconnected
    weak var delegate: DataTransferDelegate?
    
    //分包的数据
    var packets:[Data]!
    //上传包的位置
    var upLoadPacketIndex:Int = 0
    var reciviTotal:Int = 0
    // 分包配置
    private let maxPacketSize: Int = 8192
    init(isYehuo:Bool = false) {
        self.id = UUID().uuidString
        var host = NWEndpoint.Host(DEFAULTIP)
        if isYehuo {
            host = NWEndpoint.Host(YEHUODEFAULTIP)
        }
        let port = NWEndpoint.Port(rawValue:UInt16(DEFAULT_PORT))!
        self.connection = NWConnection(host: host, port: port, using: .tcp)
        setupConnection()
    }
    private func setupConnection() {
        connection.stateUpdateHandler = { [weak self] state in
            guard let self = self else { return }
            
            switch state {
            case .ready:
                self.state = .connected
                self.delegate?.connectionStateDidChange(.connected, for: self)
            case .failed(let error):
                self.state = .error(error)
                self.delegate?.connectionStateDidChange(.error(error), for: self)
                disconnect()
                
            case .waiting(let error):
                self.state = .error(error)
                self.delegate?.connectionStateDidChange(.error(error), for: self)
                disconnect()
            case .cancelled:
                self.state = .disconnected
                self.delegate?.connectionStateDidChange(.disconnected, for: self)
            default:
                break
            }
        }
    }
    // 开始接收数据
    private func startReceiving() {
        connection.receive(minimumIncompleteLength: 1, maximumLength: maxPacketSize) { [weak self] (data, context, isComplete, error) in
            guard let self = self else { return }
            if let error = error {
                self.state = .error(error)
                self.delegate?.connectionStateDidChange(.error(error), for: self)
                return
            }
                if let data = data, !data.isEmpty {
                    //如果小于，说明是上传数据
                    if self.upLoadPacketIndex < packets.count{
                        if(data.count == 8){
                                let count = data.count / 8
                                for i in 0..<count {
                                    let size:Int = Int(data[i * 8 + 0] & 0xff);
                                    let size1:Int = Int(data[i * 8 + 1] & 0xff);
                                    DebugLog("设备已接收数据： \(Int(size*256 + size1))")
                                    reciviTotal +=  Int(size*256 + size1)
                                }
                                if reciviTotal == 8192 {
                                    reciviTotal = 0
                                    sendData()
                                }
                        }
                    }else{
                        // 通知代理收到数据
                        DispatchQueue.main.async {
                            self.delegate?.didReceiveData(data, from: self)
                        }
                    }
                }
        
            switch self.state {
            case .disconnected:break
                
            case .connecting:break
                
            case .connected:
                self.startReceiving()
            case .error(_): break
                
            }
        }
    }
    // 连接TCP
    func connect() {
        state = .connecting
        delegate?.connectionStateDidChange(.connecting, for: self)
        connection.start(queue: .global())
    }
    
    // 断开连接
    func disconnect() {
        connection.cancel()
        state = .disconnected
        delegate?.connectionStateDidChange(.disconnected, for: self)
    }
    // 发送数据（自动分包）
    func sendData(_ data: Data,optType:OptionTypeEnum) {
        switch state {
        case .disconnected:
            return
        case .connecting:
            return
        case .connected: break
        case .error(let error):
            return
        }
        upLoadPacketIndex = 0
        reciviTotal = 0
        self.startReceiving()
        packets = splitDataIntoPackets(data)
        sendData()
    }
    func sendData(){
        let packet = packets[upLoadPacketIndex]
        connection.send(content: packet, completion: .contentProcessed({ [weak self] error in
            if let error = error {
                self?.state = .error(error)
                self?.delegate?.connectionStateDidChange(.error(error), for: self!)
            } else {
                self?.upLoadPacketIndex += 1
                DispatchQueue.main.async {
                    self?.delegate?.didSendData(packet, from: self!)
                    
                }
            }
        }))
    }
    
    // 数据分包
    private func splitDataIntoPackets(_ data: Data) -> [Data] {
        var packets: [Data] = []
        var offset = 0
        
        while offset < data.count {
            let chunkSize = min(maxPacketSize, data.count - offset)
            let chunk = data.subdata(in: offset..<offset + chunkSize)
            var packet = Data()
            packet.append(chunk)
            packets.append(packet)
            offset += chunkSize
        }
        return packets
    }
}
// MARK: - WiFi连接辅助
class WiFiHelper {
    // 注意：在iOS中，应用无法直接连接WiFi，需要用户手动连接
    // 这里提供一些辅助方法
    static func getCurrentSSID() ->(ssid: String, bssid: String)? {
        
        let locationManager = CLLocationManager()
        locationManager.requestWhenInUseAuthorization()
        
        // 在真实应用中，这里会使用NetworkExtension框架获取当前WiFi信息
        guard let interfaces = CNCopySupportedInterfaces() as? [String] else { return nil }
        
        for interface in interfaces {
            if let interfaceInfo = CNCopyCurrentNetworkInfo(interface as CFString) as? [String: Any] {
                        if let ssid = interfaceInfo["SSID"] as? String,
                           let bssid = interfaceInfo["BSSID"] as? String {
                            return (ssid, bssid)
                }
            }
            return nil
        }
        return nil
    }
    
    static func isConnectedToWiFi() -> Bool {
        // 检查是否连接到WiFi网络
        // 实际实现需要使用SystemConfiguration框架
        return true
    }
}
// MARK: - 错误枚举
enum WiFiError: Error {
    case unsupportediOSVersion
    case configurationFailed
    case connectionFailed
    case invalidInput
    case sftpError(String)
    case tcpError(String)
}
// MARK: - 主要WiFi工具类
class WiFiManager {
    typealias WiFiConnectionCallback = (Swift.Result<Bool, WiFiError>) -> Void
    typealias DataTransferCallback = (Swift.Result<Bool, Error>) -> Void
    
    // MARK: - WiFi连接方法
    func connectToWiFi(ssid: String, password: String? = nil, completion: @escaping WiFiConnectionCallback) {
        guard #available(iOS 11.0, *) else {
            completion(.failure(.unsupportediOSVersion))
            return
        }
        let hotspotConfiguration: NEHotspotConfiguration
        
        if let password = password {
            hotspotConfiguration = NEHotspotConfiguration(ssid: ssid, passphrase: password, isWEP: false)
        } else {
            hotspotConfiguration = NEHotspotConfiguration(ssid: ssid)
        }
        hotspotConfiguration.joinOnce = true
        
        NEHotspotConfigurationManager.shared.apply(hotspotConfiguration) { error in
            if let error = error {
                switch error.localizedDescription {
                case _ where error.localizedDescription.contains("already associated"):
                    completion(.success(true))
                case _ where error.localizedDescription.contains("canceled"):
                    completion(.failure(.connectionFailed))
                default:
                    completion(.failure(.configurationFailed))
                }
            } else {
                completion(.success(true))
            }
        }
    }
  
}

import Foundation
import NMSSH

class SFTPManager {
    
    // MARK: - Properties
    private var session: NMSSHSession?
    private var sftp: NMSFTP?
    
    // MARK: - Connection Management
    
    /// 连接到 SFTP 服务器
    func connect() -> Bool {
        session = NMSSHSession(host: YEHUODEFAULTIP, port: YEHUO_PORT, andUsername: USER)
        
        guard let session = session else { return false }
        
        session.connect()
        
        if session.isConnected {
            session.authenticate(byPassword: PASSWORD)
            if session.isAuthorized {
                sftp = NMSFTP(session: session)
                sftp?.connect()
                return sftp?.isConnected ?? false
            }
        }
        return false
    }
    /// 断开连接
    func disconnect() {
        sftp?.disconnect()
        session?.disconnect()
        sftp = nil
        session = nil
    }
    /// 检查是否已连接
    var isConnected: Bool {
        return sftp?.isConnected ?? false
    }
    
    // MARK: - File Operations
    /// 上传文件
    func uploadFile(photoInfo: PhotoInforModel,index:Int) -> Bool {
        guard isConnected else { return false }
        let remotePath = "/home/cat/Work/T2000/photo_library/" + "\(index)" + ".bmp";
        guard let data = imageToBMPSimple(photoInfo.image!) else { return false }
        return sftp?.writeContents(data, toFileAtPath: remotePath) ?? false
    }
    func getAllphotos(complateOneImage:(((Int,Int,UIImage))->Void)? = nil){
        guard isConnected else { return }
        guard let allFiles = sftp?.contentsOfDirectory(atPath: "/home/cat/Work/T2000/photo_library/") else { return  }
        let imageFiles = filterFilesByExtension(allFiles, extensions: ["bmp"])
        for i in 0..<imageFiles.count{
            let remotePath = "/home/cat/Work/T2000/photo_library/" + "\(i).bmp"
            guard let data = sftp?.contents(atPath:remotePath) else {
                return
            }
            DispatchQueue.main.async {
                guard let image = bmpDataToUIImage(data) else { return  }
                complateOneImage?((imageFiles.count,i,image))
            }
        }
    }
    func filterFilesByExtension(_ files: [NMSFTPFile], extensions: [String]) -> [NMSFTPFile] {
        return files.filter { file in
            let filename = file.filename
            let fileExtension = (filename as NSString).pathExtension.lowercased()
            return extensions.contains { $0.lowercased() == fileExtension }
        }
    }
    
    /// 重命名文件或目录
    func renameItem(oldIndex: Int, to newIndex: Int) -> Bool {
    
        let oldPath = "/home/cat/Work/T2000/photo_library/" + "\(oldIndex).bmp"
        let newPath = "/home/cat/Work/T2000/photo_library/" + "\(newIndex).bmp"
        guard isConnected else { return false }
        return sftp?.moveItem(atPath: oldPath, toPath: newPath) ?? false
    }
    
    /// 删除文件
    func deleteFile(index: Int) -> Bool {
        guard isConnected else { return false }
        let remotePath = "/home/cat/Work/T2000/photo_library/" + "\(index).bmp"
        return sftp?.removeFile(atPath: remotePath) ?? false
    }
    func deleteAll() -> Bool{
        guard isConnected else { return false }
        guard let allFiles = sftp?.contentsOfDirectory(atPath: "/home/cat/Work/T2000/photo_library/") else { return true }
        let imageFiles = filterFilesByExtension(allFiles, extensions: ["bmp"])
        
        if imageFiles.count == 0 {
            return true
        }
        for i in 0..<imageFiles.count{
            let remotePath = "/home/cat/Work/T2000/photo_library/" + "\(i).bmp"
            sftp?.removeFile(atPath: remotePath)
        }
        return true
    }
    /// 创建目录
    func createDirectory(remotePath: String) -> Bool {
        guard isConnected else { return false }
        return sftp?.createDirectory(atPath: remotePath) ?? false
    }
    
    /// 删除目录
    func deleteDirectory(remotePath: String) -> Bool {
        guard isConnected else { return false }
        return sftp?.removeDirectory(atPath: remotePath) ?? false
    }
    
    // MARK: - File Information
    /// 获取文件列表
    func listDirectory(remotePath: String) -> [NMSFTPFile] {
        guard isConnected else { return [] }
        return sftp?.contentsOfDirectory(atPath: remotePath) ?? []
    }
    /// 获取文件信息
    func fileInfo(remotePath: String) -> NMSFTPFile? {
        guard isConnected else { return nil }
        return sftp?.infoForFile(atPath: remotePath)
    }
    
    /// 检查文件是否存在
    func fileExists(remotePath: String) -> Bool {
        guard isConnected else { return false }
        return sftp?.fileExists(atPath: remotePath) ?? false
    }
    
    /// 检查是否是目录
    func isDirectory(remotePath: String) -> Bool {
        guard let fileInfo = fileInfo(remotePath: remotePath) else { return false }
        return fileInfo.isDirectory
    }
    
    // MARK: - Directory Operations
    
    /// 获取当前工作目录
    var currentDirectory: String? {
        guard isConnected else { return nil }
        // NMSFTP 没有直接提供获取当前目录的方法
        // 这里返回根目录作为默认值
        return "/"
    }
    
    /// 改变工作目录
    func changeDirectory(remotePath: String) -> Bool {
        // NMSFTP 没有直接提供改变目录的方法
        // 在实际使用中，您需要在路径中处理目录变更
        print("NMSFTP 不支持直接改变工作目录，请在路径中指定完整路径")
        return false
    }
}

// MARK: - 扩展功能
extension SFTPManager {
    
    /// 递归创建目录
//    func createDirectoryRecursively(remotePath: String) -> Bool {
//        guard isConnected else { return false }
//        
//        let components = remotePath.split(separator: "/").map(String.init)
//        var currentPath = ""
//        
//        for component in components {
//            if currentPath.isEmpty {
//                currentPath = component
//            } else {
//                currentPath += "/" + component
//            }
//            
//            if !fileExists(remotePath: currentPath) {
//                if !createDirectory(remotePath: currentPath) {
//                    return false
//                }
//            }
//        }
//        
//        return true
//    }
    
//    /// 批量上传文件
//    func uploadFiles(localPaths: [String], remoteDirectory: String, progress: ((Int, Int) -> Void)? = nil) -> [String: Bool] {
//        var results: [String: Bool] = [:]
//        
//        for (index, localPath) in localPaths.enumerated() {
//            let fileName = (localPath as NSString).lastPathComponent
//            let remotePath = "\(remoteDirectory)/\(fileName)"
//            
//            let success = uploadFile(localPath: localPath, remotePath: remotePath)
//            results[localPath] = success
//            
//            progress?(index + 1, localPaths.count)
//        }
//        
//        return results
//    }
    
    /// 获取目录大小（递归计算）
//    func directorySize(remotePath: String) -> UInt64 {
//        guard isConnected, isDirectory(remotePath: remotePath) else { return 0 }
//        
//        var totalSize: UInt64 = 0
//        let files = listDirectory(remotePath: remotePath)
//        
//        for file in files {
//            let filePath = "\(remotePath)/\(file.filename)"
//            
//            if file.isDirectory {
//                totalSize += directorySize(remotePath: filePath)
//            } else {
//                totalSize += file.fileSize
//            }
//        }
//        
//        return totalSize
//    }
}

// MARK: - 错误处理
enum SFTPError: Error {
    case notConnected
    case connectionFailed
    case authenticationFailed
    case fileNotFound
    case permissionDenied
    case unknownError(String)
}
